/**
 * @description:
 * @Author yyp
 * @time 2022/3/29
 */
public class SellTicket01 {
    public static void main(String[] args) {
        BlockRunnable01 blockRunnable01 = new BlockRunnable01();
        new Thread(blockRunnable01).start();//第 1 个线程-窗口
        new Thread(blockRunnable01).start();//第 2 个线程-窗口
        new Thread(blockRunnable01).start();//第 3 个线程-窗口
        new Thread(blockRunnable01).start();//第 1 个线程-窗口
        new Thread(blockRunnable01).start();//第 2 个线程-窗口
        new Thread(blockRunnable01).start();//第 3 个线程-窗口
        new Thread(blockRunnable01).start();//第 1 个线程-窗口
        new Thread(blockRunnable01).start();//第 2 个线程-窗口
        new Thread(blockRunnable01).start();//第 3 个线程-窗口

        //BlockThread01 blockThread01 = new BlockThread01();
//        new Thread(blockThread01).start();//第 1 个线程-窗口
//        new Thread(blockThread01).start();//第 2 个线程-窗口
//        new Thread(blockThread01).start();//第 3 个线程-窗口
    }
}

class BlockThread01 extends Thread{
    private static int ticketNum = 100;

    @Override
    public synchronized void run() {
        while(true){
            if (ticketNum <= 0) {
                System.out.println("售票结束...");
                break;
            }
            //休眠 50 毫秒, 模拟
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("窗口 " + Thread.currentThread().getName() + " 售出一张票" + " 剩余票数=" + (--ticketNum));
        }
    }
}

class BlockRunnable01 implements Runnable{//实现接口方式，使用synchronized实现线程同步
    private int ticketNum = 100;
    private boolean loop = true;
    Object o = new Object();

    public synchronized static void m1(){
        //1. public synchronized static void m1() {} 锁是加在 SellTicket03.class
    }

    public void m2(){
        //2. 如果在静态方法中，实现一个同步代码块,互斥锁还是在 this 对象
        synchronized (BlockRunnable01.class){
            System.out.println("m2");
        }
    }

    // 1. public synchronized void sell() {} 就是一个同步方法
    // 2. 这时锁在 this 对象
    // 3. 也可以在代码块上写 synchronize ,同步代码块, 互斥锁还是在 this 对象
    public /*synchronized*/ void sell01() {
        synchronized (o){
            if(ticketNum<=0){
                System.out.println("售票结束");
                loop = false;
                return;
            }
            try{
                Thread.sleep(1000);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            System.out.println("BlockRunnable01窗口："+Thread.currentThread().getName()+"售出一张票，剩余票数："+(--ticketNum));
        }
    }

    public synchronized void sell02() {
            if(ticketNum<=0){
                System.out.println("售票结束");
                loop = false;
                return;
            }
            try{
                Thread.sleep(1000);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            System.out.println("BlockRunnable01窗口："+Thread.currentThread().getName()+"售出一张票，剩余票数："+(--ticketNum));
    }

    @Override
    public void run() {
        while(loop){
//            sell01();
            sell02();
        }
    }
}
